// 暂时没有看懂
#include <bits/stdc++.h>
using namespace std;
const int INF = 1001001001; // 定义无穷大，表示未访问的格子

using P = pair<int, int>; // 坐标对类型

// 定义四个方向：上、右、下、左
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

int main() {
  int h, w; // 网格的高度和宽度
  cin >> h >> w;

  // 读取网格数据，'#'表示黑色，'.'表示白色
  vector<string> s(h);
  for (int i = 0; i < h; ++i)
    cin >> s[i];

  // step[i][j] 记录格子(i,j)在第几轮操作中被染黑（0表示初始就是黑色）
  vector<vector<int>> step(h, vector<int>(w, INF));


  vector< vector<int>      > step(h,  vector<int>(w,INF)    );

  queue<P> q; // BFS队列，用于按轮次处理

  // 将所有初始黑色格子加入队列，并设置时间戳为0（第0轮）
  for (int i = 0; i < h; ++i)
    for (int j = 0; j < w; ++j)
      if (s[i][j] == '#') {
        step[i][j] = 0; // 时间戳
        q.emplace(i, j);
      }

  int ans = 0; // 记录被黑色块的数量

  // BFS主循环：模拟染色过程
  while (q.size()) {
    ans++;

    // 从队列中取出当前处理的黑色格子
    int i, j;
    tie(i, j) = q.front();
    q.pop();
    int current_round = step[i][j]; // 当前格子被染黑的时间戳

    // 满足条件的白色格子，一定在黑块周围。检查当前格子的四个相邻格子
    for (int d = 0; d < 4; ++d) {
      int ni = i + di[d], nj = j + dj[d]; // 相邻格子坐标

      // 跳过网格外的格子
      if (ni < 0 or ni >= h or nj < 0 or nj >= w)
        continue;

      // 跳过已经染黑的格子
      if (step[ni][nj] != INF)
        continue;

      // 检查相邻格子ni,nj的四个邻居中有多少个是黑色格子
      // 根据题意：只有当白色格子恰好有1个相邻黑色格子时，才会被染黑
      int neighbor = 0;
      for (int d2 = 0; d2 < 4; ++d2) {
        int mi = ni + di[d2], mj = nj + dj[d2]; // 相邻格子的邻居坐标

        // 跳过网格外的邻居
        if (mi < 0 or mi >= h or mj < 0 or mj >= w)
          continue;

        // 如果邻居是黑色格子，计数加1
        if (step[mi][mj] <= current_round)
          neighbor++;
      }

      // 如果恰好有1个黑色邻居，则这个白色格子会在下一轮被染黑
      if (neighbor == 1) {
        step[ni][nj] = current_round + 1; // 记录被染黑的时间戳
        q.emplace(ni, nj);                // 加入队列继续扩展
      }
    }
  }

  cout << ans << '\n';

  return 0;
}